package com.pad.filelibrary.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.pad.filelibrary.interfacedir.DeleteResultListener;
import com.pad.filelibrary.interfacedir.ZipResultListener;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FileUtils2 {
    /**
     * 生成zip文件存储路径
     */
    private static final String zipFilePath = "genie_pad/collectData";
    /**
     * 临时附件位置
     */
    private static final String temporaryFilePath = "collectData/flies/";
    /**
     * 文件名称格式
     */
    private static final String fileNameFormat = "preview_frame_";
    /**
     * 文件夹最大空间 默认设置 500MB
     */
    private static final long maxDirSize = 500L * 1024 * 1024;
    /**
     * SD卡预警空间 默认设置3GB 防止影响其他功能
     */
    private static final long warningDirSize = 3L * 1024 * 1024 * 1024;
    private static String sessionIdDefult = "";
    private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
    private static FileUtils2 fileUtils2;

    public static FileUtils2 getInstance() {
        if (null == fileUtils2) {
            fileUtils2 = new FileUtils2();
        }

        return fileUtils2;
    }

    public void processFrame(byte[] data, int width, int height, int format, String sessionId) {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                dataToImage(data, width, height, format, sessionId);
            }
        });
    }

    /**
     * 相机预览回调中返回的字节数组转JPG格式图片
     *
     * @param data      相机中返回的字节数组
     * @param width     图片宽
     * @param height    图片高
     * @param format    ImageFormat.NV21 默认图片
     * @param sessionId 唯一ID
     */
    private void dataToImage(byte[] data, int width, int height, int format, String sessionId) {
        boolean isHavePermission = false;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            isHavePermission = Environment.isExternalStorageManager();
        }
        if (!isHavePermission) {
            Log.e("++ Mr.Zan ++", "processFrame: 没有相关权限");
            return;
        }
        //小于预留空间时直接返回不采集
//        if (Environment.getExternalStorageDirectory().getFreeSpace() <= warningDirSize) {
//            return;
//        }
        if (!sessionIdDefult.equals(sessionId)) {
            sessionIdDefult = sessionId;
        }

        Bitmap bitmap = null;
        // 处理YUV_420_888格式
        if (format == ImageFormat.YUV_420_888) {
            data = yuv420pToNv21(data, width, height);
        }
        try {
            YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, width, height, null);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, out);
            byte[] imageBytes = out.toByteArray();
            bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
        }catch (Exception e) {
            e.printStackTrace();
        }
        saveBitmapToJpeg(BitmapUitls.compressBitmapByPercent(bitmap, 0.8f), temporaryFilePath + sessionId, fileNameFormat + System.currentTimeMillis() + ".jpg");

    }
    /**
     * 将 YUV420P (I420) 转换为 NV21
     */
    public static byte[] yuv420pToNv21(byte[] yuv420p, int width, int height) {
        int size = width * height;
        byte[] nv21 = new byte[size * 3 / 2];

        // 复制 Y 分量
        System.arraycopy(yuv420p, 0, nv21, 0, size);

        // 获取 U 和 V 分量的起始位置
        int uStart = size;
        int vStart = size + size / 4;

        // 交错复制 U 和 V 分量
        int offset = size;
        for (int i = 0; i < size / 4; i++) {
            nv21[offset++] = yuv420p[vStart + i];  // V
            nv21[offset++] = yuv420p[uStart + i];  // U
        }

        return nv21;
    }
    private void saveBitmapToJpeg(Bitmap bitmap, String folderName, String fileName) {
        File storageDir = Environment.getExternalStorageDirectory();
        File collectDataDir = new File(storageDir, folderName);
        if (!collectDataDir.exists()) {
            if (!collectDataDir.mkdirs()) {
                return;
            }
        }
        File file = new File(collectDataDir, fileName);

        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);

            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private boolean deleteFolderContents(File directory) {
        if (directory.exists()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        deleteFolderContents(file);
                    } else {
                        file.delete();
                    }
                }
            }
        }
        return directory.delete();
    }

    /**
     * 递归计算文件夹大小
     *
     * @param file 要计算大小的文件夹或文件的 File 对象
     * @return 文件夹或文件的大小，单位为字节
     */
    private long getFolderSize(File file) {
        long size = 0;
        if (file.exists()) {
            if (file.isDirectory()) {
                // 如果是文件夹，遍历其下的所有文件和子文件夹
                File[] files = file.listFiles();
                if (files != null) {
                    for (File subFile : files) {
                        // 递归调用 getFolderSize 方法计算子文件或子文件夹的大小
                        size += getFolderSize(subFile);
                    }
                }
            } else {
                // 如果是文件，直接获取其大小
                size = file.length();
            }
        }
        return size;
    }

    /**
     * 将字节大小转换为更易读的格式（如 KB、MB、GB）
     *
     * @param size 字节大小
     * @return 格式化后的字符串
     */
    private String formatSize(long size) {
        if (size < 1024) {
            return size + " B";
        } else if (size < 1024 * 1024) {
            return String.format("%.2f KB", (double) size / 1024);
        } else if (size < 1024 * 1024 * 1024) {
            return String.format("%.2f MB", (double) size / (1024 * 1024));
        } else {
            return String.format("%.2f GB", (double) size / (1024 * 1024 * 1024));
        }
    }

    /**
     * 文件夹压缩成zip文件
     *
     * @param context
     * @param sessionId 唯一id
     */
    public void dirToZip(String sessionId, Context context) {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                boolean isHavePermission = false;
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
                    isHavePermission = Environment.isExternalStorageManager();
                }
                if (!isHavePermission) {
                    return;
                }
                //小于预留空间时直接返回不采集
                if (Environment.getExternalStorageDirectory().getFreeSpace() <= warningDirSize) {
                    return;
                }
                String sessionIdsStr = SharePreferenceUtils.getString(context, SharePreferenceKey.SESSION_ID);
                if (!TextUtils.isEmpty(sessionIdsStr)) {
                    String[] ids = sessionIdsStr.split(",");

                    if (ids.length >= 2) {
                        String sourcePath = Environment.getExternalStorageDirectory() + File.separator + temporaryFilePath + ids[0];
                        File file = new File(sourcePath);
                        if (!file.exists()) {
                            SharePreferenceUtils.setValue(context, SharePreferenceKey.SESSION_ID, ids[1] + "," + sessionId);
                            return;
                        }
                        doZip(ids[0], new DeleteResultListener() {
                            @Override
                            public void isDeleteSuccess(boolean isSuccess) {
                                if (isSuccess) {
                                    SharePreferenceUtils.setValue(context, SharePreferenceKey.SESSION_ID, ids[1] + "," + sessionId);
                                    deleteFirstCreateTimeFile();
                                    /**
                                     * 处理异常退出时的产生的数据
                                     */
                                    File file1 = new File(Environment.getExternalStorageDirectory() + File.separator + temporaryFilePath);
                                    if (file1.exists()) {
                                        File[] files = file1.listFiles();
                                        for (int i = 0; i < files.length; i++) {
                                            if (!files[i].getName().equals(ids[1]) && !files[i].getName().equals(sessionId)) {
                                                doZip(files[i].getName(), null);
                                            }
                                        }

                                    }
                                }
                            }
                        });
                    } else {
                        SharePreferenceUtils.setValue(context, SharePreferenceKey.SESSION_ID, sessionIdsStr + "," + sessionId);
                    }

                } else {
                    SharePreferenceUtils.setValue(context, SharePreferenceKey.SESSION_ID, sessionId);
                }
            }
        });


    }

    private void doZip(String sessionId, DeleteResultListener listener) {

        String sourcePath = Environment.getExternalStorageDirectory() + File.separator + temporaryFilePath + sessionId;
        String zipFileString = Environment.getExternalStorageDirectory() + File.separator + zipFilePath;
        File file = new File(sourcePath);
        if (!file.exists()) {
            return;
        }

        ZipUtils.ZipFolder(sourcePath, zipFileString, sessionId + ".zip", new ZipResultListener() {
            @Override
            public void isZipSuccess(boolean isSuccess) {
                if (isSuccess) {
                    boolean b = deleteFolderContents(new File(sourcePath));
                    if (listener != null) {
                        listener.isDeleteSuccess(b);
                    }
                }
            }
        });


    }

    /**
     * 删除最早创建的文件
     */
    private void deleteFirstCreateTimeFile() {
        long folderSize = getFolderSize(new File(Environment.getExternalStorageDirectory() + File.separator + zipFilePath));
        if (folderSize >= maxDirSize) {
            String sourcePath = Environment.getExternalStorageDirectory() + File.separator + zipFilePath;
            File folder = new File(sourcePath);

            if (folder.exists() && folder.isDirectory()) {
                // 获取文件夹中的所有文件
                File[] files = folder.listFiles();

                if (files != null) {
                    File tarFile = null;
                    // 输出排序后的文件列表
                    for (File file : files) {
                        if (tarFile == null) {
                            tarFile = file;
                        } else {
                            if (tarFile.lastModified() > file.lastModified()) {
                                tarFile = file;
                            }
                        }
                    }
                    if (tarFile != null) {
                        tarFile.delete();
                        deleteFirstCreateTimeFile();
                    }
                }
            }
        }
    }


}
